// src/characters/Character.cpp
#include "characters\Character.hh"
#include "items\item.hh"
#include <iostream>
#include <algorithm>
#include "characters/Character.hh"

Character::Character(std::string name, std::string description, unsigned int health, unsigned int maxHealth, unsigned int attack, unsigned int defense)
    : name(std::move(name)), // Use std::move for potential efficiency with strings
      description(std::move(description)),
      health(health),
      maxHealth(maxHealth),
      attackPower(attack),
      defensePower(defense)
{
    // Ensure health doesn't start above maxHealth, and handle maxHealth=0 case.
    if (this->maxHealth == 0)
    {
        this->health = 0; // Cannot be alive with 0 max health
    }
    else if (this->health > this->maxHealth)
    {
        this->health = this->maxHealth; // Clamp health to max
    }
    // std::cout << "Character '" << this->name << "' base initialized." << std::endl; // Optional debug message
}

// --- Concrete Implementations of ICharacter methods ---

bool Character::isAlive() const
{
    return health > 0;
}

bool Character::takeDamage(unsigned int damage)
{
    if (!isAlive())
    {
        return false;
    }

    unsigned int defenseReduction = defensePower / 2;
    unsigned int actualDamage = (damage > defenseReduction) ? (damage - defenseReduction) : 0;

    std::cout << name << " attempts to block (Def: " << defensePower << "/2=" << defenseReduction << "). ";

    if (actualDamage == 0)
    {
        std::cout << name << " takes no damage." << std::endl;
    }
    else if (actualDamage >= health)
    {
        health = 0; // Character is defeated
        std::cout << name << " takes " << actualDamage << " damage and is defeated!" << std::endl;
    }
    else
    {
        health -= actualDamage; // Subtract damage
        std::cout << name << " takes " << actualDamage << " damage. ("
                  << health << "/" << maxHealth << " HP remaining)" << std::endl;
    }

    return isAlive();
}

const std::string &Character::getName() const
{
    return name;
}

const std::string &Character::getDescription() const
{
    return description;
}

unsigned int Character::getHealth() const
{
    return health;
}

unsigned int Character::getMaxHealth() const
{
    return maxHealth;
}

unsigned int Character::getAttackPower() const
{
    return attackPower;
}

unsigned int Character::getDefensePower() const
{
    return defensePower;
}

unsigned int Character::getMaxdefensePower() const
{
    return maxDefensePower;
}
std::string Character::toString() const
{
    return name + " (HP: " + std::to_string(health) + "/" +
           std::to_string(maxHealth) + ", Atk: " + std::to_string(attackPower) +
           ", Def: " + std::to_string(defensePower) + ", Status: " + (isAlive() ? "Alive" : "Defeated") + ")";
}

void Character::display() const
{
    std::cout << "--- Status: " << name << " ---" << std::endl;
    std::cout << "  \"" << description << "\"" << std::endl;
    std::cout << "  Health:      " << health << " / " << maxHealth << std::endl;
    std::cout << "  Attack Power: " << attackPower << std::endl;
    std::cout << "  Defense Power:" << defensePower << std::endl;
    std::cout << "  Status:      " << (isAlive() ? "Alive" : "Defeated") << std::endl;
    std::cout << "-------------------------" << std::endl;
}

// --- Default Inventory Methods (Intended to be overridden by Player) ---
void Character::addToInventory(Item *item)
{
    std::string itemName = (item ? item->getName() : "unknown item");
    std::cerr << "[Warning] Character '" << name
              << "' does not have an inventory. Discarding item: '"
              << itemName << "'." << std::endl;

    delete item;
    item = nullptr;
}

void Character::displayInventory() const
{
    std::cout << name << " has no inventory." << std::endl;
}

// --- Helper Setters/Modifiers ---

void Character::setHealth(unsigned int newHealth)
{
    if (maxHealth == 0)
    {
        health = 0;
    }
    else
    {
        health = std::min(newHealth, maxHealth);
    }
}

void Character::setMaxHealth(unsigned int newMaxHealth)
{
    maxHealth = newMaxHealth;
    if (maxHealth == 0)
    {
        health = 0;
    }
    else if (health > maxHealth)
    {
        health = maxHealth;
    }
}

void Character::setAttackPower(unsigned int newAttack)
{
    attackPower = newAttack;
}

void Character::setDefensePower(unsigned int newDefense)
{
    defensePower = newDefense;
}
